package health_system.health_system.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.SimpleCacheErrorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.RedisConnectionFailureException;

/**
 * Redis缓存配置，提供Redis不可用时的降级处理
 */
@Slf4j
@Configuration
@EnableCaching
public class RedisCacheConfig implements CachingConfigurer {

    /**
     * 当Redis连接失败时使用的内存缓存管理器
     * 使用条件注解确保只有在没有RedisCacheManager时才创建此Bean
     */
    @Bean
    @Primary
    @ConditionalOnMissingBean(name = "cacheManager")
    public CacheManager fallbackCacheManager() {
        log.warn("Redis不可用，使用内存缓存替代");
        return new ConcurrentMapCacheManager();
    }
    
    /**
     * 自定义缓存错误处理器，当Redis不可用时不抛出异常
     */
    @Override
    @Bean
    public CacheErrorHandler errorHandler() {
        return new SimpleCacheErrorHandler() {
            @Override
            public void handleCacheGetError(RuntimeException exception, org.springframework.cache.Cache cache, Object key) {
                if (exception instanceof RedisConnectionFailureException) {
                    log.warn("Redis连接失败，忽略缓存操作: {}", exception.getMessage());
                } else {
                    super.handleCacheGetError(exception, cache, key);
                }
            }

            @Override
            public void handleCachePutError(RuntimeException exception, org.springframework.cache.Cache cache, Object key, Object value) {
                if (exception instanceof RedisConnectionFailureException) {
                    log.warn("Redis连接失败，忽略缓存操作: {}", exception.getMessage());
                } else {
                    super.handleCachePutError(exception, cache, key, value);
                }
            }

            @Override
            public void handleCacheEvictError(RuntimeException exception, org.springframework.cache.Cache cache, Object key) {
                if (exception instanceof RedisConnectionFailureException) {
                    log.warn("Redis连接失败，忽略缓存操作: {}", exception.getMessage());
                } else {
                    super.handleCacheEvictError(exception, cache, key);
                }
            }

            @Override
            public void handleCacheClearError(RuntimeException exception, org.springframework.cache.Cache cache) {
                if (exception instanceof RedisConnectionFailureException) {
                    log.warn("Redis连接失败，忽略缓存操作: {}", exception.getMessage());
                } else {
                    super.handleCacheClearError(exception, cache);
                }
            }
        };
    }
} 